iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Software Development

譯者會消失嗎?Maybe, but not today —— 你,才是更好的翻譯師系列 第 17

全鍵盤操作才是王道!commands 自定義快速鍵

  • 分享至 

  • xImage
  •  

對於翻譯工作來說,
鍵盤操作的方便性,遠比滑鼠重要許多。
我們之前還曾為了實現全鍵盤操作,
寫了不少的程式碼。

在整理快速鍵相關程式碼的過程中,
我也曾經動念,
想說是不是可以把快速鍵的設定,
變成類似 manifest.json 的做法,

結果這幾天我就發現,
原來瀏覽器外掛老早就採用這樣的做法了。
(又是個說起來都是淚的故事)

其實只要在 manifest.json 裡,
透過 commands 的設定方式,
就可以定義我們想要使用的快速鍵了:

  ...
  "commands": {
    "switchTranslation": {
      "suggested_key": {
        "default": "Alt+Up"
      },
      "description": "切換原文、譯文(請關閉 Google 翻譯)"
    }
    ...
  }
  ...

然後在 background.js 搭配下面的方式,即可調用相應的程式碼或函式。

chrome.commands.onCommand.addListener((command) => {
  ...
  switchTranslation();
  ...
});

這個做法還有個很棒的優點,
就是可以讓使用者定義自己感覺比較順手的快速鍵組合。
因為程式碼所提供的快速鍵組合,只是建議的組合,
使用者如果覺得不順手,應該要能自行改變才對。

這個做法也可以讓我們針對不同作業系統,定義不同的快速鍵。
例如 Windows 和 Mac OS,
系統預設的快速鍵有很大的不同,
鍵盤的位置也有不小的差異。
如果 Windows 某組快速鍵組合已經被 Mac OS 系統佔用,
當然就可以藉此方式改用不同的按鍵組合,以避開這類的問題。

總之,這是個很棒的功能。
如果我們要自幹這個功能,勢必得花費不小力氣,
但現在只需簡單設定,就能擁有如此方便的功能。
不用實在太可惜了。

今天就趁這個機會,
把我們的快速鍵全部轉用此機制來實現吧。

首先,我們用【Alt+上】這個切換翻譯的快速鍵來測試一下。
manifest.json 的程式碼如前,這裡就不再多述。
接著我們要把 onCommand 的程式碼,放入 background.js 之中:

chrome.commands.onCommand.addListener((command) => {
  if (command=='switchTranslation') {
    switchTranslation();
    ...
  }
});

不過,switchTranslation() 這個函式,
主要是操作網頁的【原始內容】,所以目前是放在 content.js 之中。
為了執行這個函式,我們必須使用 sengMessage 的機制:

  if (command=='switchTranslation') {
    // switchTranslation();
    chrome.tabs.query(
      {active: true, currentWindow: true}, 
      (tabs) => {
        chrome.tabs.sendMessage(
          tabs[0].id, 
          {cmd: 'switchTranslation'}
        );
      }
    );
  }

然後在 content.js 這邊,可以用 onMessage 接下這個指令,
然後再執行 switchTranslation():

chrome.runtime.onMessage.addListener( (message, sender, sendResponse) => {
  ...
  else if (message.cmd == 'switchTranslation') {
    // 【背景服務】快速鍵要求切換翻譯
    switchTranslation();
  }
  ...
}

這樣就可以了。

快速鍵轉換的過程蠻順利的,
我們再回到 manifest.json,
設定一組快速鍵【Alt+0】,用來打開快速鍵設定畫面:

  "configureCommands": {
    "suggested_key": {
      "default": "Alt+0"
    },
    "description": "開啟快速鍵設定頁面"
  },

然後在 background.js 中設定:

  ...
  else if (command=='configureCommands') {
    chrome.tabs.create({url: "chrome://extensions/configureCommands"});
  }
  ...

這樣就可以用【Alt+0】打開快速鍵設定頁面,
你可以試著改變快速鍵組合,換成你自己覺得順手的按法,
修改完馬上就會生效喲!

https://ithelp.ithome.com.tw/upload/images/20221002/20115241TwElwTBKja.png

其他的快速鍵應該可以依此類推,
於是我就把所有的快速鍵,全都照搬了過去,
然後重新載入外掛。。。

https://ithelp.ithome.com.tw/upload/images/20221002/20115241IO8kMie2Hy.png

什麼?出問題了!!
每個外掛最多只能設定 4 組 commands 快速鍵?!

那我忙了一整天,究竟是在忙什麼東西呀??!!

抱著死馬當活馬醫的心情,
我再次請教 Google,才發現了這篇說明
(內容是英文,我們的外掛正好可以派上用場 ^_^)

簡單的說,最多 4 個的限制,是寫死在程式碼中無法改變的。
不過,commands 的數量其實沒有限制,
有限制的是 suggested_key,
也就是最多只能設定 4 組「建議的」快速鍵。

因此,我保留了「調出快速鍵設定畫面」的【Alt+0】這組快速鍵,
其他的 suggested_key 全都移除,
這樣就可以順利載入外掛了。

原本我利用 hotkeys 來設定快速鍵的方式,還是保留了起來,
可用來做為預設的快速鍵設定,
這樣正好補足了 suggested_key 數量限制的缺憾。
另一方面,藉由 commands 的設定,
則可以讓使用者定義自己想用的快速鍵。

如果同一組快速鍵,在預設設定與自定義設定中,分別被設為不同的功能,
那麼使用者自定義的快速鍵組合,就會優先被採用,
而原本預設的功能,也就不會再被執行了(等於是被覆蓋掉了)。

這兩種做法互相搭配、相輔相成,功能上也就沒什麼遺憾了。

有幾點要注意的是:

  • onCommands 要放在 background.js,但我們大部分的快速鍵都是在操作網頁的【原始內容】,所以只能透過 sendMessage 機制傳送指令到 content.js,再進行相應的處理。至於我們原本的做法,包含快速鍵的觸發與處理函式都是放在 content.js,大部分都不需要用到 sendMessage 的機制(除了請【背景服務】向外部取得譯文之外),因此我們原本的程式碼相對比較簡潔一些。

  • 不過,commands 放在 background.js 也有其合理性。畢竟快速鍵屬於外掛的功能,如果放在 content.js,等於每開啟一個新的頁面,都要重新設定一次快速鍵;如果放在 background.js,就只會在啟用外掛時設定一次,感覺上比較合理。

  • 快速鍵的說明,保存在 manifest.json 裡也是比較合理的做法。這樣一來,content.js 裡就不需要再重複保存快速鍵說明了。我們會把 content.js 裡的快速鍵說明移除,只留下快速鍵名稱與快速鍵處理函式的對應關係。

  • 由於快速鍵說明保存在 manifest.json 中,因此【彈出頁面】若要取得快速鍵的說明,只要利用 chrome.commands.getAll() 即可,不需要再利用 sendMessage 機制向 content.js 索取資訊了。

我們的程式碼經過一番整理之後,目前增添快速鍵的流程如下:

  • manifest.json:在 commands 項目內,添加「快速鍵組合名稱」與相應的「說明」。

    • 建議按鍵(suggested_key)只能添加 4 組,所以盡量不在此添加建議按鍵組合
    • 「快速鍵組合名稱」的規範如下:
      • 根據各個快速鍵的名稱,依照 Ctrl、Alt、Shift、「一般按鍵」的順序串聯而成。
      • 0~9、a~z、Enter、Esc、Up、Down、Left、Right 與各種符號,皆可視為「一般按鍵」。
  • background.js:在 chrome.commands.onCommand 內添加判斷邏輯。如果要送往 content.js 處理,只要符合前述的快速鍵名稱規範,此處就不必添加任何程式碼,即可直接交由 content.js 進行後續處理。

  • content.js:在 hotkey_cmd 這個變數中,填入符合規範的快速鍵名稱,與相應的處理函式。然後再建立相應的處理函式即可。

好啦,今天在過程中雖然被嚇了一大跳,
但以結果來說,應該還算令人滿意啦。
希望這裡所採用的做法,
可提供給大家做為參考囉。


上一篇
保存設定的各種姿勢——chrome.storage 與 options 選項頁面
下一篇
許我一個滑動的句子面板
系列文
譯者會消失嗎?Maybe, but not today —— 你,才是更好的翻譯師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言